/**
 * 
 */
package com.golden.gamedev.object.background;

import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.io.Serializable;

import com.golden.gamedev.object.collision.CollisionRect;
import com.golden.gamedev.object.collision.CollisionShape;
import com.golden.gamedev.object.collision.Dimensionable;

/**
 * The {@link BaseBackground} class provides a default mutable implementation of
 * a {@link Background} that can be used as-is or extended. If used as is,
 * however, certain functionality, such as {@link #render(Graphics2D) rendering}
 * and {@link #update(long) updating}, will perform no operations. <br />
 * <br />
 * Methods available to be overridden are the following: (Does nothing by
 * default) {@link #update(long)} <br />
 * (Does nothing by default) {@link #render(Graphics2D)} <br />
 * (Has a sensible default implementation)
 * {@link #setBounds(double, double, int, int)} <br />
 * (Has a sensible default implementation) {@link #setSize(int, int)} <br />
 * (Has a sensible default implementation) {@link #setLocation(double, double)} <br />
 * <br />
 * If either {@link #setSize(int, int)} or {@link #setLocation(double, double)}
 * are overridden, they must invoke the super invocation at some point to
 * actually set the values to store into this {@link BaseBackground} instance.
 * 
 * @author MetroidFan2002
 * @version 1.0
 * @since 0.2.4
 * @see Background
 * 
 */
public class BaseBackground implements Background {
	
	/**
	 * {@link Serializable} ID generated by Eclipse.
	 */
	private static final long serialVersionUID = 1L;
	
	private final CollisionRect delegateCollisionShape = new CollisionRect();
	
	private final Rectangle clip = new Rectangle();
	
	/**
	 * Creates a new {@link BaseBackground} instance.
	 */
	public BaseBackground() {
		super();
	}
	
	public final Rectangle getClip() {
		return new Rectangle(clip);
	}
	
	public final void setClip(Rectangle rectangle) {
		this.clip.setBounds(rectangle);
	}
	
	public void setSize(int width, int height) {
		this.delegateCollisionShape.setHeight(height);
		this.delegateCollisionShape.setWidth(width);
	}
	
	public final void setToCenter(Dimensionable center) {
		this.setLocation(center.getX() + (center.getWidth() / 2)
		        - (this.clip.width / 2), center.getY()
		        + (center.getHeight() / 2) - (this.clip.height / 2));
	}
	
	public void update(long elapsedTime) {
		// Intentionally blank
	}
	
	public void render(Graphics2D g) {
		// Intentionally blank
	}
	
	public final boolean intersects(CollisionShape shape) {
		return this.delegateCollisionShape.intersects(shape);
	}
	
	public final void move(final double dx, final double dy) {
		this.setLocation(this.delegateCollisionShape.getX() + dx,
		        this.delegateCollisionShape.getY() + dy);
	}
	
	public void setBounds(double x1, double y1, int w1, int h1) {
		this.setSize(w1, h1);
		this.setLocation(x1, y1);
	}
	
	public final void setHeight(int height) {
		this.setSize(this.delegateCollisionShape.getWidth(), height);
	}
	
	public void setLocation(double x, double y) {
		this.delegateCollisionShape.setLocation(x, y);
	}
	
	public final void setWidth(int width) {
		this.setSize(width, this.delegateCollisionShape.getHeight());
	}
	
	public final int getHeight() {
		return this.delegateCollisionShape.getHeight();
	}
	
	public final int getWidth() {
		return this.delegateCollisionShape.getWidth();
	}
	
	public final double getX() {
		return this.delegateCollisionShape.getX();
	}
	
	public final double getY() {
		return this.delegateCollisionShape.getY();
	}
	
	public final void setX(double x) {
		this.setLocation(x, this.delegateCollisionShape.getY());
	}
	
	public final void setY(double y) {
		this.setLocation(this.delegateCollisionShape.getX(), y);
	}
}
